#include "../utils/utils.hpp"
#include "literal.hpp"
#include "entity.hpp"

namespace mashine { namespace kb {

using namespace std;

Literal::Literal() : Entity<string>("", vector<string>())
{
	APP_LOGGER(info) << "Literal {" << "empty" << "} instantiated";
}

Literal::Literal(string name, vector<string> params, bool denied)
		: Entity<string>(name, params)
{
	this->denied = denied;
	
	APP_LOGGER(info) << "Literal {" << toString() << "} instantiated";
}

Literal::Literal(Literal const & literal) : Entity<string>(literal)
{
	this->denied = literal.denied;
	
	APP_LOGGER(info) << "Literal {" << literal.toString() << "} copied";
}

Literal::~Literal()
{
	APP_LOGGER(info) << "Literal {" << toString() << "} begins to break down";
}

/**
 * need owerride this method in child class 
 * to correct work Entity constructor
 */
bool Literal::validateName() const
{
	APP_LOGGER(info) << "Literal {" << toString() << "} name validating begin";
	
	return utils::is_predicate_name(name);
}

/**
 * need owerride this method in child class 
 * to correct work Entity constructor
 */
bool Literal::validateParam() const
{
	APP_LOGGER(info) << "Literal {" << toString() << "} params validating begin";
	
	for (vector<string>::const_iterator i = params.begin(); i != params.end(); ++i)
    {
        if (utils::is_variable_name(*i) || utils::is_constant_name(*i) ) {} else 
		{
			return false;
		}
    }
	
	return true;
}

bool Literal::isFact() const
{
    for (vector<string>::const_iterator i = params.begin(); i != params.end(); ++i) 
    {
        if (utils::is_variable_name(*i))
        {
            return false;
        }
    }

    return true;
}

bool Literal::isDenied() const
{
	return denied;
}

void Literal::setDenied(bool denied)
{
	this->denied = denied;
}

string Literal::toString() const
{
	if (name.length() == 0) 
		return "empty";
		
    string ret;

	if (denied) ret += "~";
	
    ret += name;
    ret += "(";

    vector<string>::const_iterator i;
    for (i = params.begin(); i != params.end(); i++)
    {
		ret += *i + ", ";
    }
	
	if (params.size() != 0) 
	{
		ret.erase(ret.size() - 2, 2);
    }
	
    return ret + ")";
}

Literal Literal::operator~() const
{
	return Literal(this->name, this->params, !this->denied);
}

// Literal & operator = (const Literal & l)
// {
	// this->name = l.name;
	// this->params = l.params;
	
	// return *this;
// }

}}